package com.songlanyun.modules.wechat.service;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.RedisUtils;
import com.songlanyun.modules.wechat.config.WxMaConfiguration;
import com.songlanyun.modules.wechat.entity.TemplateData;
import com.songlanyun.modules.wechat.entity.WxMssVo;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * 发送小程序订阅消息
 */
@Service
@Slf4j
public class SendWxMessage {


    @Autowired
    private RedisUtils redisUtils;

    private final static int accessTokenExpire = 5000;

    @Value("${wx.miniapp.sendUrl}")
    private String sendUrl;
    @Value("${wx.miniapp.tokenUrl}")
    private String tokenUrl;

    @Value("${wx.miniapp.configs[0].appid}")
    private String appId;

    @Value("${wx.miniapp.configs[0].secret}")
    private String secret;

    /*
     * 发送订阅消息
     * */
    public String push(String openid, String template_id, Map<String, TemplateData> templateParam) {
        log.info(String.format("发送模板消息，openid:【%s】,template_id:【%s】", openid, template_id));

        if (StringUtils.isBlank(openid) || StringUtils.isBlank(template_id)) {
            return "";
        }
        RestTemplate restTemplate = new RestTemplate();

        //根据template_id 得到此微信模板vo
        //这里简单起见我们每次都获取最新的access_token（时间开发中，应该在access_token快过期时再重新获取）
        String key = openid + "access_token";
        String access_token = getAccessToken(key);

        String url = this.sendUrl + access_token;
        //拼接推送的模版
        WxMssVo wxMssVo = new WxMssVo();
        wxMssVo.setTouser(openid);//用户的openid（要发送给那个用户，通常这里应该动态传进来的）
        wxMssVo.setTemplate_id(template_id);//订阅消息模板id
        wxMssVo.setPage("pages/index/index");
        wxMssVo.setData(templateParam);
        String body = "";//记录微信返回消息
        ResponseEntity<String> responseEntity =
                restTemplate.postForEntity(url, wxMssVo, String.class);
        body = responseEntity.getBody(); //43101 小程序未授权

        Map<String, Object> map = (Map<String, Object>) JSON.parse(body);
        Integer errcode = MapUtil.getInt(map, "errcode");
        String errmsg = MapUtil.getStr(map, "errmsg");
        log.info(String.format("模板消息返回结果，errcode：【%s】,errmsg:【%s】", errcode, errmsg));

//        //解决access_token过期异常
        if (errcode == 40001) {//access_token过期,删除key，重新生成
            redisUtils.delete(key);
            this.push(openid, template_id, templateParam);
        }

        log.info(String.format("模板消息发送成功，openid:【%s】,template_id:【%s】", openid, template_id));
        return body;
    }


    public String getAccessToken(String key) {
        String accessToken = redisUtils.get(key);
        if (StringUtils.isNotBlank(accessToken)) {
            return accessToken;
        }
        final WxMaService wxService = WxMaConfiguration.getMaService(appId);
        try {
            accessToken = wxService.getAccessToken(true);
            redisUtils.set(key, accessToken, accessTokenExpire);
        } catch (WxErrorException ex) {
            throw new RRException(ex.getMessage());
        }

        return accessToken;
    }
}
